#ifndef AST_PROGRAM
#define AST_PROGRAM
#include <string>
#include <list>
#include "node.h"

namespace AST {

    /**
     * Programa
     *
     * Estrutura inicial de uma árvore abstrata de sintaxe resultado das
     * produções na linguagem. Recebe como parâmetro um conjunto de nós
     * processados durante a leitura da entrada ao compilador.
     *
     * @category AST
     * @package  AST
     */
    class Program : public Node {

    private:

        /**
         * Declarações do Programa
         */
        std::list<Node*>* _declarations;

        /**
         * Configura as Declarações do Programa
         *
         * Recebe como parâmetro todas as declarações encontradas no programa e
         * que foram transformadas em nós de árvore abstrata de sintaxe. Este
         * conjunto é formado por elementos construídos durante a produção de
         * gramática sobre a entrada.
         *
         * @param  std::list<Node*>* Elemento para Configuração
         * @return Próprio Objeto para Encadeamento
         */
        Program* _setDeclarations(std::list<Node*>*);

    public:

        /**
         * Construtor
         *
         * Estrutura responsável pelo recebimento de todas as declarações
         * produzidas no programa fornecido como entrada ao compilador.
         *
         * @param std::list<Node>* Conjunto de Declarações do Programa
         */
        Program(std::list<Node*>*);

        /**
         * Construtor sem Declarações
         *
         * Programa definido sem declarações, conforme descrição da gramática
         * que permite este tipo de entrada
         */
        Program();

        /**
         * Apresenta as Declarações do Programa
         *
         * Exibe o conjunto construído com as informações do programa que foram
         * construídas durante a produção da gramática sobre a entrada.
         *
         * @return Conjunto Elemento Solicitado
         */
        std::list<Node*>* getDeclarations();

        // Sobrescrita
        std::string toString(int);

        // Especialização
        std::string toString();

    };

};

#endif

